//
//  CS_LocalMusicViewController.swift
//  NewSS
//
//  Created by 杨馥瑞 on 2021/9/6.
//

import UIKit

class CS_LocalMusicViewController: CS_BaseViewController {
    
    private enum UIStatus {
        case empty      // 没有音乐
        case normal     // 正常状态
        case manager    // 进入管理
    }
    
    var hadAddmusicListDidUpdated: (([CS_MusicModel])->Void)?
    
    private lazy var _emptyView: CS_LocalMusicEmptyView = _getEmptyView()   // 列表为空时
    private lazy var _naviRightItem: UIBarButtonItem = _getNaviRightItem()  // 导航栏右侧按钮
    private lazy var _listView: CS_LocalMusicListView = _getListView()      // 音乐列表
    private lazy var _bottomView: CS_LocalMusicBottomView = _getBottomView() // 底部的操作栏
    private var _viewModel: CS_LocalMusicViewModel = CS_LocalMusicViewModel()
    private var _uiStatus: UIStatus = .empty

    override func viewDidLoad() {
        super.viewDidLoad()
        _initUI()
        _initListener()
        _initData()
    }
    
    // MARK: - 事件处理
    
    @objc private func _rightNaviItemClick() {
        guard _uiStatus != .empty else { return }
        _uiStatus == .normal ? _changeUIStatusTo(.manager, isInit: false) : _changeUIStatusTo(.normal, isInit: false)
        if _uiStatus == .normal, _viewModel.musicList.isEmpty {
            _changeUIStatusTo(.empty, isInit: false)
        }
    }
    
    // MARK: - 私有方法
    
    private func _initUI() {
        view.backgroundColor = .white
        navigationItem.title = "本地音乐"
        navigationItem.rightBarButtonItem = _naviRightItem
        
        _viewModel.musicList.isEmpty ? _changeUIStatusTo(.empty, isInit: true) : _changeUIStatusTo(.normal, isInit: true)
    }
    
    private func fixScale(_ value: CGFloat) -> CGFloat {
        return ceil(value*kScreenWidth / 375)
    }
    
    private func _initData() {
        _viewModel.refresh()
    }
    
    private func _initListener() {
        _emptyView.importFromComputerClick = {
            CS_ImportFromWIFIView.show()
        }
        
        _emptyView.importFromRemoteLibraryClick = { [weak self] in
            self?.present(CS_ImportMusicFromLibraryViewController(), animated: true)
        }
        
        _viewModel.musicListDidUpdated = { [weak self] musicList in
            guard let self = self else { return }
            if musicList.isEmpty {
                self._changeUIStatusTo(.empty, isInit: false)
            }
            else if self._uiStatus == .manager {
                self._changeUIStatusTo(.manager, isInit: false)
            }
            else {
                self._changeUIStatusTo(.normal, isInit: false)
            }
            
            // 筛选已经被添加的音乐
            var hadAddMusics = [CS_MusicModel]()
            musicList.forEach { musicCellModel in
                if let music = musicCellModel.music, music.isAdded {
                    hadAddMusics.append(music)
                }
            }
            self.hadAddmusicListDidUpdated?(hadAddMusics)
        }
        
        _listView.cellHandleButtonClick = { [weak self] index in
            guard let music = self?._viewModel.musicList[index] else { return }
            music.isManagerMode ? self?._handleDeleteStatusClick(music) : self?._handleOtherStatusClick(index)
        }
        
        _listView.cellClick = { [weak self] index in
            guard let music = self?._viewModel.musicList[index], !music.isManagerMode else { return }
            self?._handleOtherStatusClick(index)
        }
    }
    
    private func _changeUIStatusTo(_ newStatus: UIStatus, isInit: Bool) {
        
        let bottomViewHeight: CGFloat = fixScale(49) + kSafeAreaBottom
        
        func _showBottomView() {
            if !view.subviews.contains(_bottomView) {
                view.addSubview(_bottomView)
                _bottomView.snp.makeConstraints { make in
                    make.left.right.equalToSuperview()
                    make.top.equalTo(view.snp.bottom).offset(-bottomViewHeight)
                    make.height.equalTo(bottomViewHeight)
                }
            }
            
            _bottomView.snp.updateConstraints { $0.top.equalTo(view.snp.bottom).offset(-bottomViewHeight) }
            UIView.animate(withDuration: 0.3) {
                self.view.layoutIfNeeded()
            }
        }
        
        func _hideBottomView() {
            guard _bottomView.superview != nil else { return }
            _bottomView.snp.updateConstraints { $0.top.equalTo(view.snp.bottom) }
            UIView.animate(withDuration: 0.3) {
                self.view.layoutIfNeeded()
            }
        }
        
        func switchStatus(_ status: UIStatus) {
            switch newStatus {
            case .empty:
                if !view.subviews.contains(_emptyView) {
                    view.addSubview(_emptyView)
                    if #available(iOS 15, *) {
                        _emptyView.snp.makeConstraints { make in
                            make.top.equalTo(kNavigationBarHeight)
                            make.left.bottom.right.equalToSuperview()
                        }
                    }
                    else {
                        _emptyView.snp.makeConstraints { $0.edges.equalToSuperview() }
                    }
                }
                _emptyView.isHidden = false
                _listView.isHidden = true
                _naviRightItem.isEnabled = false
                _naviRightItem.title = ""
                navigationItem.title = "本地音乐"
                
                _hideBottomView()
            case .normal:
                _showBottomView()
                
                if !view.subviews.contains(_listView) {
                    view.addSubview(_listView)
                    _listView.snp.makeConstraints { make in
                        make.left.top.right.equalToSuperview()
                        make.bottom.equalTo(_bottomView.snp.top)
                    }
                }
                _emptyView.isHidden = true
                _naviRightItem.isEnabled = true
                _naviRightItem.title = "管理"
                navigationItem.title = "本地音乐"
                _viewModel.musicList.forEach { $0.isManagerMode = false }
                _listView.isHidden = false
                _listView.updateDataSource(_viewModel.musicList)
                
            case .manager:
                _emptyView.isHidden = true
                _naviRightItem.isEnabled = true
                _naviRightItem.title = "完成"
                navigationItem.title = "管理本地音乐"
                _viewModel.musicList.forEach { $0.isManagerMode = true }
                _listView.isHidden = false
                _listView.updateDataSource(_viewModel.musicList)
                
                _hideBottomView()
            }
        }
        
        _uiStatus = newStatus
        switchStatus(newStatus)
    
    }
    
    private func _handleOtherStatusClick(_ index: Int) {
        _viewModel.updateMusic(index)
        _listView.updateMusic(_viewModel.musicList[index])
    }
    
    private func _handleDeleteStatusClick(_ music: CS_MusicCellModel) {
        _viewModel.removeMusic(music)
        _listView.removeMusic(music)
    }
    
    // MARK: - 懒加载
    
    private func _getEmptyView() -> CS_LocalMusicEmptyView {
        let view = CS_LocalMusicEmptyView()
        view.isUserInteractionEnabled = true
        return view
    }
    
    private func _getNaviRightItem() -> UIBarButtonItem {
        let item = UIBarButtonItem(title: "管理", style: .plain, target: self, action: #selector(_rightNaviItemClick))
        item.setTitleTextAttributes([.foregroundColor : UIColor.black, .font : kFont(kPingFangSCSemibold, 17)], for: .normal)
        return item
    }
    
    private func _getListView() -> CS_LocalMusicListView {
        let listView = CS_LocalMusicListView(frame: .zero)
        return listView
    }
    
    private func _getBottomView() -> CS_LocalMusicBottomView {
        let bottomView = CS_LocalMusicBottomView()
        bottomView.clickClosure = { [weak self] clickType in
            switch clickType {
            case .fromWifi:
                CS_ImportFromWIFIView.show()
            case .fromNet:
                self?.present(CS_ImportMusicFromLibraryViewController(), animated: true)
            }
        }
        return bottomView
    }

}

private class CS_MusicCellModel: Equatable {
    
    static func == (lhs: CS_MusicCellModel, rhs: CS_MusicCellModel) -> Bool {
        return lhs.music?.identifier == rhs.music?.identifier
    }
    
    
    enum Status {
        case normal     // 未添加
        case hadAdd     // 已添加
    }
    
    var isManagerMode = false   // true：管理模式；false：正常模式
    var status: Status = .normal
    var music: CS_MusicModel?
    var iconName: String {
        if isManagerMode {
            return "room_music_delete"
        }
        else {
            switch status {
            case .normal: return "room_music_add"
            case .hadAdd: return "room_music_downloaded"
            }
        }
    }
    
    init(music: CS_MusicModel) {
        self.music = music
        status = music.isAdded ? .hadAdd : .normal
    }
    
}

private class CS_LocalMusicViewModel {
    
    var musicListDidUpdated: (([CS_MusicCellModel])->Void)?
    
    private(set) var musicList: [CS_MusicCellModel] = [CS_MusicCellModel]()
    
    init() {
        NotificationCenter.default.addObserver(self, selector: #selector(_musicListDidUpdatedNotification(_:)), name: NSNotification.Name(rawValue: CS_MusicManager.shared.musicListDidUpdatedNotificationName), object: nil)
    }
    
    // MARK: - 通知
    
    @objc private func _musicListDidUpdatedNotification(_ notification: NSNotification) {
        _refreshMusicListBy(CS_MusicManager.shared.queryAllMusics())
    }
    
    // MARK: - 外部方法
    
    func refresh() {
        _refreshMusicListBy(CS_MusicManager.shared.musicList)
    }
    
    func removeMusic(_ music: CS_MusicCellModel) {
        if musicList.contains(music) {
            musicList = musicList.filter { $0 != music }
            if let musicModel = music.music {
                CS_MusicManager.shared.removeMusic(musicModel)
            }
        }
    }
    
    func updateMusic(_ index: Int) {
        guard index >= 0,
              index < musicList.count,
              let music = musicList[index].music,
              (musicList[index].status == .hadAdd || musicList[index].status == .normal)
        else { return }
        musicList[index].status = musicList[index].status == .hadAdd ? .normal : .hadAdd
        musicList[index].music?.isAdded = musicList[index].status == .hadAdd
        CS_MusicManager.shared.updateMusic(music)
    }
    
    private func _refreshMusicListBy(_ newMusicList: [CS_MusicModel]) {
        self.musicList = newMusicList.map { CS_MusicCellModel(music: $0) }
        musicListDidUpdated?(self.musicList)
    }
    
}

private class CS_LocalMusicListView: UIView, UITableViewDelegate, UITableViewDataSource {
    
    var cellHandleButtonClick: ((Int)->Void)?
    var cellClick: ((Int)->Void)?
    
    private lazy var _dataSource: [CS_MusicCellModel] = [CS_MusicCellModel]()
    private lazy var _tableView: UITableView = _getTableView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        _initUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 外部方法
    
    func updateDataSource(_ dataSource: [CS_MusicCellModel]) {
        _dataSource = dataSource
        _tableView.reloadData()
    }
    
    func removeMusic(_ music: CS_MusicCellModel) {
        var index = -1
        for (idx, value) in _dataSource.enumerated() {
            if value == music {
                index = idx
                break
            }
        }
        guard index != -1 else { return }
        _dataSource.remove(at: index)
        _tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
    }
    
    func updateMusic(_ music: CS_MusicCellModel) {
        var index = -1
        for (idx, value) in _dataSource.enumerated() {
            if value == music {
                index = idx
                break
            }
        }
        guard index != -1 else { return }
        _dataSource[index] = music
        _tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
    }
    
    // MARK: - 代理
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return _dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: CS_LocalMusicListCell = tableView.dequeueReusableCell(indexPath: indexPath)
        let music = _dataSource[indexPath.row]
        cell.name = music.music?.musicName ?? ""
        cell.singerName = music.music?.singerName ?? ""
        cell.handleButtonIconName = music.iconName
        cell.handleButtonClickClosure = { [weak self] in
            self?.cellHandleButtonClick?(indexPath.row)
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        cellClick?(indexPath.row)
    }
    
    // MARK: - 私有方法
    
    private func _initUI() {
        addSubview(_tableView)
        _tableView.snp.makeConstraints { $0.edges.equalToSuperview() }
    }
    
    private func _getTableView() -> UITableView {
        let tableView = UITableView(frame: .zero, style: .plain)
        tableView.register(CS_LocalMusicListCell.self)
        tableView.rowHeight = fixScale(62)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView(frame: .zero)
        return tableView
    }
    
    // MARK: - Cell
    
    private class CS_LocalMusicListCell: UITableViewCell {
        
        var handleButtonClickClosure: (()->Void)?
        
        var name = "" {
            didSet {
                _nameLabel.text = name
            }
        }
        
        var singerName = "" {
            didSet {
                _singerNameLabel.text = singerName
            }
        }
        
        var handleButtonIconName = "" {
            didSet {
                _handleButton.setImage(UIImage(named: handleButtonIconName), for: .normal)
            }
        }
        
        private lazy var _nameLabel: UILabel = _getNameLabel()
        private lazy var _singerNameLabel: UILabel = _getSingerNameLabel()
        private lazy var _handleButton: UIButton = _getHandleButton()
        private var _music: CS_MusicCellModel?
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            _initUI()
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        // MARK: - 事件处理
        
        @objc private func _handleButtonClick() {
            handleButtonClickClosure?()
        }
        
        // MARK: - 私有方法
        
        private func _initUI() {
            contentView.addSubview(_nameLabel)
            contentView.addSubview(_singerNameLabel)
            contentView.addSubview(_handleButton)
            
            _nameLabel.snp.makeConstraints { make in
                make.left.equalTo(fixScale(16))
                make.top.equalTo(fixScale(13))
                make.right.equalTo(_handleButton.snp.left).offset(-fixScale(14))
            }
            
            _singerNameLabel.snp.makeConstraints { make in
                make.left.right.equalTo(_nameLabel)
                make.top.equalTo(_nameLabel.snp.bottom).offset(fixScale(1))
            }
            
            _handleButton.snp.makeConstraints { make in
                make.width.height.equalTo(fixScale(50))
                make.centerY.equalToSuperview()
                make.right.equalTo(-fixScale(10))
            }
        }
        
        private func _getNameLabel() -> UILabel {
            let label = UILabel()
            label.font = kFont(kPingFangSCSemibold, 15)
            label.textColor = .colorT1
            return label
        }
        
        private func _getSingerNameLabel() -> UILabel {
            let label = UILabel()
            label.font = kFont(kPingFangSCSemibold, 13)
            label.textColor = .colorT3
            return label
        }
        
        private func _getHandleButton() -> UIButton {
            let button = UIButton(type: .custom)
            button.addTarget(self, action: #selector(_handleButtonClick), for: .touchUpInside)
            return button
        }
        
    }
    
}

private class CS_LocalMusicBottomView: UIView {
    
    enum ClickType {
        case fromWifi
        case fromNet
    }

    var clickClosure: ((ClickType)->Void)?
    
    private lazy var _stackView: UIStackView = _getStackView()
    private lazy var _lineView: UIView = _getLineView()
    private lazy var _importFromWifiButton: UIButton = _getImportFromWifiButton()
    private lazy var _importFormNetButton: UIButton = _getImportFromNetButton()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        _initUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 事件处理
    
    @objc private func _importFromWifiClick() {
        clickClosure?(.fromWifi)
    }
    
    @objc private func _importFromNetClick() {
        clickClosure?(.fromNet)
    }
    
    // MARK: - 私有方法
    
    private func _initUI() {
        addSubview(_stackView)
        addSubview(_lineView)
        
        _stackView.snp.makeConstraints { make in
            make.left.right.top.equalToSuperview()
            make.height.equalTo(fixScale(49))
        }
        _stackView.addArrangedSubviews([_importFromWifiButton, _importFormNetButton])
        
        _lineView.snp.makeConstraints { make in
            make.left.top.right.equalToSuperview()
            make.height.equalTo(0.5)
        }
    
    }
    
    private func _getStackView() -> UIStackView {
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.distribution = .fillEqually
        return stackView
    }
    
    private func _getLineView() -> UIView {
        let line = UIView()
        line.backgroundColor = .hexString("#F2F2F2")
        return line
    }
    
    private func _getImportFromWifiButton() -> UIButton {
        let button = UIButton(type: .custom)
        button.setTitle("从电脑导入音乐", for: .normal)
        button.setTitleColor(.colorT2, for: .normal)
        button.titleLabel?.font = kFont(kPingFangSCSemibold, 14)
        button.setImage(UIImage(named: "room_music_import_from_computer"), for: .normal)
        button.addTarget(self, action: #selector(_importFromWifiClick), for: .touchUpInside)
        button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 0)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 4)
        return button
    }
    
    private func _getImportFromNetButton() -> UIButton {
        let button = UIButton(type: .custom)
        button.setTitle("从曲库导入音乐", for: .normal)
        button.setTitleColor(.colorT2, for: .normal)
        button.titleLabel?.font = kFont(kPingFangSCSemibold, 14)
        button.setImage(UIImage(named: "room_music_import_from_net"), for: .normal)
        button.addTarget(self, action: #selector(_importFromNetClick), for: .touchUpInside)
        button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 0)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 4)
        return button
    }
    
}

private class CS_LocalMusicEmptyView: UIView {
    
    var importFromComputerClick: (()->Void)?
    var importFromRemoteLibraryClick: (()->Void)?
    
    private lazy var _tipsLabel: UILabel = _getTipsLabel()
    private lazy var _importFromComputerButton: UIButton = _getImportFromComputerButton()
    private lazy var _importFromRemoteLibraryButton: UIButton = _getImportFromRemoteLibraryButton()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        _commonInit()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 事件
    
    @objc private func _importFromComputerClick() {
        importFromComputerClick?()
    }
    
    @objc private func _importFromRemoteLibraryClick() {
        importFromRemoteLibraryClick?()
    }
    
    // MARK: - 私有方法
    
    private func _commonInit() {
        addSubview(_tipsLabel)
        addSubview(_importFromComputerButton)
        addSubview(_importFromRemoteLibraryButton)
        
        _tipsLabel.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(fixScale(43))
        }
        
        _importFromComputerButton.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(_tipsLabel.snp.bottom).offset(fixScale(38))
            make.width.equalTo(fixScale(315))
            make.height.equalTo(fixScale(44))
        }
        
        _importFromRemoteLibraryButton.snp.makeConstraints { make in
            make.top.equalTo(_importFromComputerButton.snp.bottom).offset(fixScale(16))
            make.width.height.centerX.equalTo(_importFromComputerButton)
        }
        
    }
    
    private func _getTipsLabel() -> UILabel {
        let label = UILabel()
        label.text = "暂无本地音乐"
        label.font = kFont(kPingFangSCRegular, 13)
        label.textColor = .hexString("#999999")
        return label
    }
    
    private func _getImportFromComputerButton() -> UIButton {
        let button = UIButton(type: .custom)
        button.setTitle("从电脑导入", for: .normal)
        button.setTitleColor(.hexString("#666666"), for: .normal)
        button.titleLabel?.font = kFont(kPingFangSCSemibold, 15)
        button.setImage(UIImage(named: "room_music_import_from_computer"), for: .normal)
        button.addTarget(self, action: #selector(_importFromComputerClick), for: .touchUpInside)
        button.layer.cornerRadius = fixScale(22)
        button.layer.borderWidth = 1
        button.layer.borderColor = UIColor.hexString("d8d8d8").cgColor
        button.layer.masksToBounds = true
        button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 6, bottom: 0, right: 0)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 6)
        return button
    }
    
    private func _getImportFromRemoteLibraryButton() -> UIButton {
        let button = UIButton(type: .custom)
        button.setTitle("从曲库导入", for: .normal)
        button.setTitleColor(.hexString("#666666"), for: .normal)
        button.titleLabel?.font = kFont(kPingFangSCSemibold, 15)
        button.setImage(UIImage(named: "room_music_import_from_net"), for: .normal)
        button.addTarget(self, action: #selector(_importFromRemoteLibraryClick), for: .touchUpInside)
        button.layer.cornerRadius = fixScale(22)
        button.layer.borderWidth = 1
        button.layer.borderColor = UIColor.hexString("d8d8d8").cgColor
        button.layer.masksToBounds = true
        button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 6, bottom: 0, right: 0)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 6)
        return button
    }
}
